<template>
  <view
    class="step"
    :class="[
      { finish: status === 'finish', process: status === 'process', 'is-first': isFirst, 'is-last': isLast },
      `step--${direction}`,
      `step--text-${textAlign}`,
    ]"
    :style="[getStyle]"
  >
    <view class="step__header">
      <view class="step__line1" />
      <view class="step__num" :class="{ 'step__num--text': slotDefault, 'step__num--dot': !slotDefault }">
        <slot :process="status === 'process'" :finish="status === 'finish'" :is-first="isFirst" />
      </view>
      <view class="step__line2" />
    </view>
    <view class="step__content">
      <view class="step__title">
        <view>
          <template v-if="$slots.title">
            <slot
              name="title"
              :process="status === 'process'"
              :finish="status === 'finish'"
              :is-first="isFirst"
              :is-last="isLast"
            />
          </template>
          <template v-else>
            {{ $t(title) }}
          </template>
        </view>
        <view v-if="$slots['sub-title'] || subTitle" class="step__sub-title">
          <template v-if="$slots['sub-title']">
            <slot
              name="sub-title"
              :process="status === 'process'"
              :finish="status === 'finish'"
              :is-first="isFirst"
              :is-last="isLast"
            />
          </template>
          <template v-else>
            {{ $t(subTitle) }}
          </template>
        </view>
      </view>
      <view class="step__content">
        <template v-if="$slots.content">
          <slot
            name="content"
            :process="status === 'process'"
            :finish="status === 'finish'"
            :is-first="isFirst"
            :is-last="isLast"
          />
        </template>
        <template v-else>
          {{ $t(content) }}
        </template>
      </view>
    </view>
  </view>
</template>

<script lang="ts">
import { defineComponent, inject, onMounted, onUnmounted, reactive, toRefs, computed } from '@vue/composition-api'

export default defineComponent({
  props: {
    title: {
      type: String,
      default: '',
    },
    subTitle: {
      type: String,
      default: '',
    },
    content: {
      type: String,
      default: '',
    },
    icon: {
      type: String,
      default: null,
    },
    iconColor: {
      type: String,
      default: '',
    },
    size: {
      type: [String, Number],
      default: '12px',
    },
    slotDefault: {
      // 小程序的$slots.default v-if不好使
      type: Boolean,
      default: false,
    },
  },
  options: {
    virtualHost: true, //  将自定义节点设置成虚拟的，更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等，而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
  },
  setup(props) {
    const stepParent: any = inject('stepParent', null)
    const stepParentReactive: any = reactive(stepParent)
    const state = reactive({
      status: '',
      isFirst: false,
      isLast: false,
      direction: stepParent.direction,
      textAlign: stepParent.textAlign,
    })
    let label
    const setStep = (label, value) => {
      if (label < value) {
        state.status = 'finish'
      } else if (label === value) {
        state.status = 'process'
      } else {
        state.status = ''
      }
    }

    const setFirstAndList = (label, stepList) => {
      if (!stepList.length) {
        return
      }

      const index = stepList.findIndex((x) => x.label === label)
      state.isFirst = index === 0
      state.isLast = index === stepList.length - 1
    }

    const getStyle = computed(() => {
      let obj: any = {}

      if (stepParent.direction === 'horizontal') {
        // obj.width = 100 / stepParentReactive.stepList.length + '%'
      } else {
        obj.paddingLeft = stepParentReactive.space + 'rpx'
      }

      return obj
    })

    onMounted(async () => {
      if (stepParent && stepParent.addStep) {
        label = stepParent.stepList.length

        stepParent.addStep({
          label,
          title: props.title,
          content: props.content,
          vm: {
            setStep,
            setFirstAndList,
          },
        })
      }
    })

    onUnmounted(async () => {
      if (stepParent && stepParent.removeStep) {
        stepParent.removeStep(label)
      }
    })

    return {
      ...toRefs(state),
      getStyle,
    }
  },
})
</script>
<style lang="scss" scoped>
.step {
  &__header {
    text-align: center;
    display: flex;
    align-items: center;
    margin-bottom: 8rpx;
  }
  &__line1 {
    flex: 1;
    min-width: 0;
    background-color: #e5e5e5;
    .is-first & {
      visibility: hidden;
    }
  }
  &__line2 {
    flex: 1;
    min-width: 0;
    background-color: #e5e5e5;
    .is-last & {
      visibility: hidden;
    }
  }
  &__num {
    position: relative;
    z-index: 1;
    display: inline-block;
    &::before {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translateX(-50%) translateY(-50%);
      background-color: #ffe5e5;

      border-radius: 100%;
      z-index: -1;
    }
    &::after {
      content: '';
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translateX(-50%) translateY(-50%);
      background-color: #e5e5e5;
      border-radius: 100%;
      z-index: -1;
    }
  }
  &__title {
    font-size: 24rpx;
    color: #c2cdd2;
    margin-bottom: 8rpx;
    display: flex;
    align-items: center;
    font-size: 30rpx;
  }
  &__sub-title {
    color: $--font-primary-c;
    padding: 0 8rpx;
  }
  &__content {
    font-size: 24rpx;
    color: $--font-secondary-c;
  }
  &.finish,
  &.process {
    .step__num {
      &::after {
        background-color: #248dfa;
      }
    }
    .step__title {
      color: #248dfa;
    }
    .step__content {
      color: $--font-primary-c;
    }
  }
  &.process {
    .step__num {
      &::before {
        content: '';
      }
    }
  }
  &--text-right {
    .step__title {
      justify-content: space-between;
    }
    .step__content {
      text-align: right;
    }
  }
  &--horizontal {
    display: flex;
    flex-direction: column;
    flex: 1;
    .step__content {
      text-align: center;
    }
    .step__line1,
    .step__line2 {
      height: 1rpx;
    }
    .step__num {
      width: 36rpx;
      height: 36rpx;
      margin: 0 8rpx;
      &::before {
        width: 36rpx;
        height: 36rpx;
      }
      &::after {
        width: 18rpx;
        height: 18rpx;
      }
    }
    .step__title {
      justify-content: center;
    }
    &.finish,
    &.process {
      .step__line1,
      .step__line2 {
        height: 4rpx;
        background-color: #248dfa;
      }
      .step__num {
        &::after {
          width: 20rpx;
          height: 20rpx;
        }
      }
    }
  }
  &--vertical {
    position: relative;
    padding-bottom: 32rpx;
    width: 100%;
    .step__header {
      position: absolute;
      top: 10rpx;
      left: 0;
      width: 20rpx;
      bottom: 0;
      flex-direction: column;
      .step__line1 {
        display: none;
      }
    }
    .step__line1,
    .step__line2 {
      width: 1rpx;
    }
    .step__num {
      &--dot {
        width: 20rpx;
        height: 20rpx;
        margin-bottom: 8rpx;
        &::before {
          width: 20rpx;
          height: 20rpx;
        }
        &::after {
          width: 10rpx;
          height: 10rpx;
        }
      }
      &--text {
        width: 40rpx;
        height: 40rpx;
        margin-bottom: 8rpx;
        margin-top: -10rpx;
        color: #fff;
        &::before {
          width: 40rpx;
          height: 40rpx;
        }
        &::after {
          width: 40rpx;
          height: 40rpx;
        }
      }
    }

    .step__content {
    }
    &.finish,
    &.process {
      .step__num {
        &--dot {
          &::after {
            width: 12rpx;
            height: 12rpx;
          }
        }
      }
    }
    &.process {
      .step__title {
        font-size: 28rpx;
      }
      .step__sub-title {
        color: #248dfa;
      }
    }
    &.finish {
      .step__line2 {
        height: 1rpx;
        background-color: #248dfa;
      }
    }
    &.is-last {
      padding-bottom: 0 !important;
    }
  }
}
</style>
